using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System;

namespace JufGame
{
	[CustomPropertyDrawer(typeof(LOD_Feature))]
	public class Feature_Inspector : PropertyDrawer
	{
		private ReorderableList configs;
		private readonly bool[] markEnum = new bool[(int)AI_LOD.Length_DontSelect];
		private struct SelectConfigs
		{
			public ReorderableList CurConfigs;
			public int LODEnum;
		}
		public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
		{
			EditorGUI.BeginProperty(position,label,property);
			EditorGUIUtility.labelWidth = 50;
			position.height = EditorGUIUtility.singleLineHeight;

			var eFeatureRect = new Rect(position)
			{
				width = 75,
			};
			var lODIdxlRect = new Rect(eFeatureRect)
			{
				width = position.width - 80,
				x = eFeatureRect.x + 80,
			};
			var configsRect = new Rect(eFeatureRect)
			{
				x = position.x,
				width = position.width,
				y = eFeatureRect.y + EditorGUIUtility.singleLineHeight * 2.3f,
			};
			var foldedOutRect = new Rect(configsRect)
			{
				x = configsRect.x - 4,
				y = configsRect.y - EditorGUIUtility.singleLineHeight * 1.2f,
			};
			var eFeatureProperty = property.FindPropertyRelative("E_Feature");
			var lODIdxProperty = property.FindPropertyRelative("curIndex");
			EditorGUI.PropertyField(eFeatureRect, eFeatureProperty);
			lODIdxProperty.intValue = EditorGUI.IntSlider(lODIdxlRect, new GUIContent("拟定LOD") ,lODIdxProperty.intValue, 0, configs.count - 1);
			property.isExpanded = EditorGUI.BeginFoldoutHeaderGroup(foldedOutRect, property.isExpanded, new GUIContent("特征LOD列表"));
			#if false
			DrawConfigs(property.FindPropertyRelative("configs"));
			if (property.isExpanded)
			{
				configs.DoList(configsRect);
			}
			#else
			EditorGUI.PropertyField(configsRect, property.FindPropertyRelative("configs"));
			#endif
			EditorGUI.EndFoldoutHeaderGroup();
        	EditorGUI.EndProperty();
			property.serializedObject.ApplyModifiedProperties();
		}
		private void DrawConfigs(SerializedProperty property)
		{
			configs = new ReorderableList(property.serializedObject, property, true, false, true, true)
			{
				drawElementCallback = (Rect rect, int index, bool selected, bool focused) =>
				{
					var element = configs.serializedProperty.GetArrayElementAtIndex(index);
					UpdateMark(configs);
					EditorGUI.PropertyField(rect,element);
				},
				elementHeightCallback = (index) =>
				{
					var space = EditorGUIUtility.standardVerticalSpacing;
					SerializedProperty element = configs.serializedProperty.GetArrayElementAtIndex(index);
					var lodEnum = element.FindPropertyRelative("lOD");
					var cost = element.FindPropertyRelative("cost");
					return EditorGUI.GetPropertyHeight(lodEnum) + EditorGUI.GetPropertyHeight(cost) + space * 10;
				},
				onCanRemoveCallback = (ReorderableList l) =>
				{
					return l.count > 2;
				},
				onCanAddCallback = (ReorderableList l) =>
				{
					return l.count < (int)AI_LOD.Length_DontSelect;
				},
				onAddDropdownCallback = (Rect buttonRect, ReorderableList l) =>
				{
					var menu = new GenericMenu();
					for(int i = 0; i < (int)AI_LOD.Length_DontSelect; ++i) 
					{
						if(!markEnum[i])
						{
							menu.AddItem(new GUIContent(((AI_LOD)i).ToString()), false, ClickHandler, 
										new SelectConfigs{CurConfigs = l, LODEnum = i});
						}
					}
					menu.ShowAsContext();
				},
			};
		}

        private void ClickHandler(object userData)
        {
			var configs = (SelectConfigs)userData;
            var index = configs.CurConfigs.serializedProperty.arraySize;
			configs.CurConfigs.serializedProperty.arraySize++;
			configs.CurConfigs.index = index;
			var element = configs.CurConfigs.serializedProperty.GetArrayElementAtIndex(index);
			element.FindPropertyRelative("lOD").enumValueIndex = configs.LODEnum;
			element.FindPropertyRelative("cost").vector4Value = Vector4.one;
			configs.CurConfigs.serializedProperty.serializedObject.ApplyModifiedProperties();
			markEnum[configs.LODEnum] = true;
			SortConfigs(configs.CurConfigs);
        }
		private void UpdateMark(ReorderableList l)
		{
			var elements = l.serializedProperty;
			for(int i = 0; i < (int)AI_LOD.Length_DontSelect; ++i)
			{
				markEnum[i] = false;
			}	
			for(int i = 0; i < l.count; ++i)
			{
				markEnum[elements.GetArrayElementAtIndex(i).FindPropertyRelative("lOD").enumValueIndex] = true;
			}	
		}
		private void SortConfigs(ReorderableList l)
		{
			SerializedProperty elements = l.serializedProperty;
			int count = elements.arraySize;
			int[] sortedEnum = new int[count];
			Vector4[] sortedCost = new Vector4[count];
			for (int i = 0; i < count; i++)
			{
				sortedEnum[i] = elements.GetArrayElementAtIndex(i).FindPropertyRelative("lOD").enumValueIndex;
				sortedCost[i] = elements.GetArrayElementAtIndex(i).FindPropertyRelative("cost").vector4Value;
			}
			Array.Sort(sortedEnum, (a, b) =>
			{
				int sortingValueA = a;
				int sortingValueB = b;
				return sortingValueA.CompareTo(sortingValueB);
			});
			for (int i = 0; i < count; i++)
			{
				elements.GetArrayElementAtIndex(i).FindPropertyRelative("lOD").enumValueIndex = sortedEnum[i];
				elements.GetArrayElementAtIndex(i).FindPropertyRelative("cost").vector4Value = sortedCost[i];
			}
			elements.serializedObject.ApplyModifiedProperties();
		}
    }
}

